The following is a conjoint analysis for a breakfast product to be sold in Tokyo, mainly targeting office professionals.
The research will include six attributes. Conventional attributes:
Innovative attributes:
Loading the data and creating the attribute:
# load required libraries
library(conjoint)
library(dplyr)
library(purrr)
library(readxl)
library(usethis)
library(ggplot2)
library(knitr)
library(googlesheets4)
library(forcats)
library(tidyr)
library(gridExtra)
library(tidytext)
library(tidyr)
library(wordcloud)
library(reshape2)
library(syuzhet)
library(wordcloud)
library(topicmodels)
library(utf8)
library(readxl)
library(textdata)
library(lubridate)
library(plotly)
library(GGally)
library(factoextra)
library(cluster)
# source custom functions from sensei
source("SCRIPTS/conjoint_tool_new.R")
source("SCRIPTS/cltool_new.R")
# define the attributes
attribute <- list(
Price = c("200", "400", "600"),
Form = c("Bread and Pastries","Onigiri","Protein sticks"),
PurchaseLocation = c("On Route to work","Within 150m", "More than 150m"),
FunPackaging = c("None", "Attack on Titan", "Doan Ritsu"),
CognitiveSupport = c("None","Caffeine or Alertness boost",
"Natural Mood Stabilizer"),
DigitalIntegration = c("None", "Loyalty points", "Nutrition Advice")
)
kable(data.frame(attribute))
| Price | Form | PurchaseLocation | FunPackaging | CognitiveSupport | DigitalIntegration |
|---|---|---|---|---|---|
| 200 | Bread and Pastries | On Route to work | None | None | None |
| 400 | Onigiri | Within 150m | Attack on Titan | Caffeine or Alertness boost | Loyalty points |
| 600 | Protein sticks | More than 150m | Doan Ritsu | Natural Mood Stabilizer | Nutrition Advice |
To generate the combinations for the survey, we run:
# Step 2: Profile Construction
# Full factorial design
profiles <- expand.grid(attribute)
# Orthogonal design
design.o <- caFactorialDesign(data=profiles, type="fractional", cards=13)
# Assigning incremental id for clarity
design.o.p <- tibble::rowid_to_column(design.o, "ID")
# Assigning variable for part-worth calculation
brkfst_design <- design.o
# Displaying table
kable(design.o.p)
| ID | Price | Form | PurchaseLocation | FunPackaging | CognitiveSupport | DigitalIntegration |
|---|---|---|---|---|---|---|
| 1 | 600 | Bread and Pastries | More than 150m | Attack on Titan | None | None |
| 2 | 200 | Protein sticks | On Route to work | Doan Ritsu | None | None |
| 3 | 400 | Onigiri | More than 150m | None | Caffeine or Alertness boost | None |
| 4 | 600 | Onigiri | On Route to work | Attack on Titan | Natural Mood Stabilizer | None |
| 5 | 400 | Bread and Pastries | Within 150m | Doan Ritsu | Natural Mood Stabilizer | None |
| 6 | 400 | Bread and Pastries | On Route to work | None | None | Loyalty points |
| 7 | 600 | Onigiri | More than 150m | Doan Ritsu | None | Loyalty points |
| 8 | 200 | Bread and Pastries | Within 150m | Attack on Titan | Caffeine or Alertness boost | Loyalty points |
| 9 | 400 | Protein sticks | More than 150m | Attack on Titan | Natural Mood Stabilizer | Loyalty points |
| 10 | 400 | Onigiri | Within 150m | Attack on Titan | None | Nutrition Advice |
| 11 | 600 | Protein sticks | Within 150m | None | Caffeine or Alertness boost | Nutrition Advice |
| 12 | 400 | Bread and Pastries | On Route to work | Doan Ritsu | Caffeine or Alertness boost | Nutrition Advice |
| 13 | 200 | Bread and Pastries | More than 150m | None | Natural Mood Stabilizer | Nutrition Advice |
Proceeding with loading the data from the survey:
## reading the survey data
#Read google sheets data into R
brkfst <- read_excel("DATA/DDM_MCU_survey.xlsx",
sheet = "Form Responses 1")
Before starting the analysis, we sanitize the data. Given that country input was free-hand with no pre-built validation, we take a look at the values collected:
# check country
brkfst %>%
group_by(country) %>%
summarize(n = n())
## # A tibble: 19 × 2
## country n
## <chr> <int>
## 1 Bangladesh 2
## 2 Bulgaria 1
## 3 China 11
## 4 India 4
## 5 Japan 10
## 6 Korea 1
## 7 Malaysia 2
## 8 Mongolia 1
## 9 Myanmar 1
## 10 PHILIPPINES 1
## 11 Philippines 2
## 12 Romania 2
## 13 Singapore 6
## 14 South Korea 1
## 15 TW 1
## 16 Taiwan 6
## 17 Thailand 3
## 18 Vietnam 4
## 19 singapore 2
We proceed to santize the country variable, and roll-up
into a region variable:
# sanitize county
brkfst <-
brkfst %>%
mutate(country2 = case_when(country == "TW" ~ "Taiwan",
country == "singapore" ~ "Singapore",
country == "PHILIPPINES" ~ "Philippines",
TRUE ~ country))
# check country
brkfst %>%
group_by(country2) %>%
summarize(n = n())
## # A tibble: 16 × 2
## country2 n
## <chr> <int>
## 1 Bangladesh 2
## 2 Bulgaria 1
## 3 China 11
## 4 India 4
## 5 Japan 10
## 6 Korea 1
## 7 Malaysia 2
## 8 Mongolia 1
## 9 Myanmar 1
## 10 Philippines 3
## 11 Romania 2
## 12 Singapore 8
## 13 South Korea 1
## 14 Taiwan 7
## 15 Thailand 3
## 16 Vietnam 4
# create region
brkfst <- brkfst %>%
mutate(region = case_when(
country2 %in% c("Taiwan", "China", "Japan", "Korea",
"Mongolia", "South Korea") ~ "East Asia",
country2 %in% c("Singapore", "Malaysia", "Thailand", "Vietnam",
"Myanmar", "Philippines" ) ~ "South-East Asia",
country2 %in% c("India", "Bangladesh") ~ "Indian subcontinent",
country2 %in% c("Bulgaria", "Romania", "Slovakia",
"United States") ~ "Western",
TRUE ~ country))
# check region
brkfst %>%
group_by(region) %>%
summarize(n = n())
## # A tibble: 4 × 2
## region n
## <chr> <int>
## 1 East Asia 31
## 2 Indian subcontinent 6
## 3 South-East Asia 21
## 4 Western 3
We further roll-up some variables, with low number of observations in some levels that are similar to others.
# roll up working starting time
brkfst %>%
group_by(work_start) %>%
summarize(n = n())
## # A tibble: 5 × 2
## work_start n
## <chr> <int>
## 1 07:00~08:00 2
## 2 08:00~09:00 17
## 3 09:00~10:00 30
## 4 After 10:00 10
## 5 Before 07:00 2
brkfst <- brkfst %>%
mutate(work_start_cut =
case_when(
work_start %in% c("Before 07:00", "07:00~08:00", "08:00~09:00") ~ "Before 9:00",
work_start %in% c("09:00~10:00", "After 10:00") ~ "After 9:00"
))
brkfst %>%
group_by(work_start_cut) %>%
summarize(n = n())
## # A tibble: 2 × 2
## work_start_cut n
## <chr> <int>
## 1 After 9:00 40
## 2 Before 9:00 21
# roll up exercise per week
brkfst <- brkfst %>%
mutate(exercise_per_week_cut =
case_when(
exercise_per_week %in% c("< 1") ~ "Never",
exercise_per_week %in% c("1-3", "4-5") ~ "1-5 times"
))
brkfst %>%
group_by(exercise_per_week_cut) %>%
summarize(n = n())
## # A tibble: 2 × 2
## exercise_per_week_cut n
## <chr> <int>
## 1 1-5 times 42
## 2 Never 19
Next step is to generate part worth utilies, based on responents preference for the product combinations.
# ratings cut
brkfst_rating <-
brkfst %>%
select(starts_with("PROD"))
# generating partworths
brkfst_part <- ca.part.util(brkfst_rating ,brkfst_design, attribute)
Before visualizing, we need to combine the partworth estimations with the initial data:
## Combine parthworth-demographics -----
### combine parth worth utilities with main data frame
brkfst_cmb <-
cbind(brkfst, brkfst_part) %>%
### deal with duplicated 'none' column
rename(L_10_None = 39,
L_13_None = 42,
L_16_None = 45,
)
### rename with long ordered columns
brkfst_cmb <-
brkfst_cmb %>%
rename(L_1_200 = 30 ,
L_2_400 = 31,
L_3_600 = 32,
`L_4_Bread and Pastries` = 33,
L_5_Onigiri = 34,
`L_6_Protein sticks` = 35,
`L_7_On Route to work` = 36,
`L_8_Within 150m` = 37,
`L_9_More than 150m` = 38,
L_10_None = 39,
`L_11_Attack on Titan` = 40 ,
`L_12_Doan Ritsu` = 41,
`L_13_None`= 42,
`L_14_Caffeine or Alertness boost` = 43,
`L_15_Natural Mood Stabilizer` = 44,
L_16_None = 45 ,
`L_17_Loyalty points` = 46,
`L_18_Nutrition Advice` = 47
)
To get the parthworth utilies for all the sample, We compute the column means and plot the result. These values are also used for trade-off analysis:
#overall average utilities
average_utility <- colMeans(brkfst_part)
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
kable(average_utility_df %>%
select(lng_level, avg_utility, group),
col.names = c("Level", "Utility", "Attribute"))
| Level | Utility | Attribute |
|---|---|---|
| L_1_200 | 0.5127049 | Price |
| L_2_400 | 0.0590656 | Price |
| L_3_600 | -0.5717541 | Price |
| L_4_Bread and Pastries | 0.1385902 | Form |
| L_5_Onigiri | 0.4702295 | Form |
| L_6_Protein sticks | -0.6087377 | Form |
| L_7_On Route to work | 0.5010328 | PurchaseLocation |
| L_8_Within 150m | -0.1460328 | PurchaseLocation |
| L_9_More than 150m | -0.3550492 | PurchaseLocation |
| L_10_None | 0.3676230 | FunPackaging |
| L_11_Attack on Titan | -0.1200820 | FunPackaging |
| L_12_Doan Ritsu | -0.2476393 | FunPackaging |
| L_13_None | -0.1534918 | CognitiveSupport |
| L_14_Caffeine or Alertness boost | 0.0520656 | CognitiveSupport |
| L_15_Natural Mood Stabilizer | 0.1013934 | CognitiveSupport |
| L_16_None | -0.2792131 | DigitalIntegration |
| L_17_Loyalty points | 0.3036230 | DigitalIntegration |
| L_18_Nutrition Advice | -0.0243770 | DigitalIntegration |
# kable(brkfst_desc_slice,
# col.names = c("Observations", "Level","Utility", "Attribute"))
Visualizing the partworth utilities for all the sample is done with the following code.
ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste("All sample", length(brkfst$nickname), sep = ", n=")) +
guides(fill="none")
To evaluate relative ordinal preference, we can sort descending by utility:
## all sample parthworth utilities - sorted descending
plot_list <- list()
n_obs = length(brkfst_cmb$nickname)
iter = "All sample"
brkfst_desc_slice <- brkfst_cmb %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
# kable(brkfst_desc_slice,
# col.names = c("Observations", "Level","Utility", "Attribute"))
ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none") +
theme(legend.position="bottom")
Going further, we plot the importance overall first.
# Importance - # Overall all sample
kable(ca.importance(brkfst_part, attribute),
col.names = "Attribute importance")
| Attribute importance | |
|---|---|
| Price | 0.2424731 |
| Form | 0.2412452 |
| PurchaseLocation | 0.1914105 |
| FunPackaging | 0.1375659 |
| CognitiveSupport | 0.0569895 |
| DigitalIntegration | 0.1303157 |
Visualizing importance for the whole sample:
## plot importance overall
sub_importance <-
ca.importance(brkfst_part, attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste("All sample", length(brkfst$nickname), sep = ", n=")) +
guides(fill="none")
It can be observed that for the whole sample, there are two variables
that are very closely tied together: Price with 24% and
Form with 24%. This suggests likely a trade-off between two
different needs (low price and personal taste), which can be
investigated through segmentation.
We turn to subgroups. First, we explore the parthworth utility by gender:
#segmenting part-worth utilities
# =====
# gender
plot_list <- list()
var_by = brkfst$gender
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, length(brkfst$nickname), sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by gender, we can sort descending:
# gender- sorted descending
plot_list <- list()
var_by = brkfst_cmb$gender
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none") +
theme(legend.position="bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
Subsequently, the importance of gender becomes:
#breakdown of importance by subcomponents
#### by gender
plot_list <- list()
var_by = brkfst$gender
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Turning to region, the partworth utilities:
#segmenting part-worth utilities
# =====
# region
plot_list <- list()
var_by = brkfst$region
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by region, we can sort descending:
# region - sorted descending
plot_list <- list()
var_by = brkfst_cmb$region
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance of region is as follows.
#### by region
plot_list <- list()
var_by = brkfst$region
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Turning to Age, the parthworth utilities are:
#segmenting part-worth utilities
# =====
# age
plot_list <- list()
var_by = brkfst$age
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by age, we can sort descending:
# age - sorted descending
plot_list <- list()
var_by = brkfst_cmb$age
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance of Age is as follows.
# importance
#### by age
plot_list <- list()
var_by = brkfst$age
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Exploring by whether a person is leaving with their partner or not. The partworth utilities of Civil Status are:
#segmenting part-worth utilities
# =====
# living with partner
plot_list <- list()
var_by = brkfst$living_with_partner
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by civil status, we can sort descending:
# civil status - sorted descending
plot_list <- list()
var_by = brkfst_cmb$living_with_partner
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance of Civil Status is:
# importance
#### by living with partner
plot_list <- list()
var_by = brkfst$living_with_partner
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Reflecting career ladder status and aspirations. The partworth utilities are:
#segmenting part-worth utilities
# =====
# living with partner
plot_list <- list()
var_by = brkfst$expected_salary
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by expected salary, we can sort descending:
# expected salary - sorted descending
plot_list <- list()
var_by = brkfst_cmb$expected_salary
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance thus is:
#### by expected salary
plot_list <- list()
var_by = brkfst$expected_salary
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Exploring the impact of personal dietary restrictions. Partworth utilities are:
#segmenting part-worth utilities
# =====
# dietary restriction
plot_list <- list()
var_by = brkfst$dietary_restrictions
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by dietary restrictions, we can sort descending:
# dietary restrictions - sorted descending
plot_list <- list()
var_by = brkfst_cmb$dietary_restrictions
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance is:
## importance
#### by dietary restriction
plot_list <- list()
var_by = brkfst$dietary_restrictions
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
Breaking down by the time that the work day starts. The parthworth utilities:
#segmenting part-worth utilities
# =====
# work_start cut
plot_list <- list()
var_by = brkfst$work_start_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by work start time, we can sort descending:
# work start cut - sorted descending
plot_list <- list()
var_by = brkfst_cmb$work_start_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The work start importance:
#### by work start
plot_list <- list()
var_by = brkfst$work_start_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
The number of times a person exercises per week. Partworth utilities:
#segmenting part-worth utilities
# =====
# exercise per week cut
plot_list <- list()
var_by = brkfst$exercise_per_week_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by exercise frequency, we can sort descending:
# exercise frequency - sorted descending
plot_list <- list()
var_by = brkfst_cmb$exercise_per_week_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance is:
#### by exercise per week
plot_list <- list()
var_by = brkfst$exercise_per_week_cut
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
How much a person’s love for drinking influences their breakfast preferences. The parthworth utilities:
#segmenting part-worth utilities
# =====
# alcohol per week
plot_list <- list()
var_by = brkfst$alcohol_per_week
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
average_utility <- colMeans(brkfst_part[var_by==iter,,drop=FALSE])
average_utility_df <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df <-
average_utility_df %>%
filter(level != "intercept")
average_utility_df <-
average_utility_df %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df <- average_utility_df %>%
mutate(rank = seq.int(1:length(average_utility_df$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(average_utility_df, aes(x=lng_level, y = avg_utility
,fill = group_fct
))+
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(avg_utility, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To visualize relative importance by alcohol consumption, we can sort descending:
# alcohol consumption - sorted descending
plot_list <- list()
var_by = brkfst_cmb$alcohol_per_week
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_cmb[var_by == iter,1])
brkfst_desc_slice <- brkfst_cmb[var_by == iter,] %>%
mutate(item_col = iter) %>%
group_by(item_col) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-item_col) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(group_aggr =
factor(group_aggr, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
))) %>%
arrange(desc(value)) %>%
ungroup
#kable(brkfst_desc_slice)
plot_list[[i]] <- ggplot(brkfst_desc_slice,
aes(x= reorder(name,value), y = value
,fill = group_aggr
))+
geom_col() +
coord_flip() +
#scale_x_discrete(limits = rev(levels(average_utility_df$lng_level))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n=")) +
#guides(fill="none")
theme(legend.position = "bottom")
}
grid.arrange(grobs=plot_list,ncol=2)
The importance of alcohol consumption:
#### by alcohol per week
plot_list <- list()
var_by = brkfst$alcohol_per_week
attr_levels <- unique(var_by)
for (i in seq_along(attr_levels)) {
iter = attr_levels[i]
n_obs = length(brkfst_part[var_by == iter,1])
sub_importance <-
ca.importance(brkfst_part[var_by == iter,], attribute)
sub_importance_df <- data.frame(
sub_importance = sub_importance,
attribute_txt = names(sub_importance)
)
sub_importance_df <- sub_importance_df %>%
mutate(group_fct = factor(attribute_txt, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
plot_list[[i]] <- ggplot(sub_importance_df, aes(x=group_fct, y = sub_importance,
fill=group_fct)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = rev(levels(sub_importance_df$group_fct))) +
geom_text(aes(label = format(round(sub_importance, 2), nsmall = 2)), vjust = -0.5) +
ggtitle(paste(iter, n_obs, sep = ", n =")) +
guides(fill="none")
}
grid.arrange(grobs=plot_list,ncol=2)
To gain insight into behavioral subgroups, we run a segmentation analysis. To decide the number of clusters, we first look at the silhouette plot.
# exclude intercept column
brkfst_part_sg <- data.frame(brkfst_part[,-1])
names(brkfst_part_sg)[10] <- c("No special packaging")
names(brkfst_part_sg)[13] <- c("No cognitive support")
names(brkfst_part_sg)[16] <- c("No digital integration")
# silhouette plot
fviz_nbclust(brkfst_part_sg, kmeans, method="silhouette")
Estimating four clusters:
# estimating clusters
brkfst_sg_4 <- k.means(brkfst_part_sg, n.cluster=4)
# Cluster sizes
prop.table(brkfst_sg_4$size)
## [1] 0.36065574 0.27868852 0.26229508 0.09836066
# interpreting clusters
snake.ch2(brkfst_sg_4)
#Cluster plot
fviz_cluster(brkfst_sg_4, brkfst_part_sg, ellipse.type = "convex",
ggtheme = theme_minimal())
Estimating seven clusters:
# estimating clusters
brkfst_sg_7 <- k.means(brkfst_part_sg, n.cluster=7)
# Cluster sizes
prop.table(brkfst_sg_7$size)
## [1] 0.13114754 0.09836066 0.26229508 0.09836066 0.14754098 0.08196721 0.18032787
# interpreting clusters
snake.ch2(brkfst_sg_7)
#Cluster plot
fviz_cluster(brkfst_sg_7, brkfst_part_sg, ellipse.type = "convex",
ggtheme = theme_minimal())
To visualize composition of each cluster - we create a table of each cluster.
To view individual names, we have to replace the variable
"country2" with "nickname" in the code
below.
## segment composition -----
# For analysis: Keep as separate vectors
brkfst_clst <- cbind(brkfst_cmb,
cluster = brkfst_sg_4$cluster)
cluster1_names <- brkfst_clst[brkfst_clst$cluster == 1, "country2"]
cluster2_names <- brkfst_clst[brkfst_clst$cluster == 2, "country2"]
cluster3_names <- brkfst_clst[brkfst_clst$cluster == 3, "country2"]
cluster4_names <- brkfst_clst[brkfst_clst$cluster == 4, "country2"]
# For presentation: Create NA-padded data frame
presentation_df <- data.frame(
cluster1 = c(cluster1_names, rep(NA, length(cluster1_names) - length(cluster1_names))),
cluster2 = c(cluster2_names, rep(NA, length(cluster1_names) - length(cluster2_names))),
cluster3 = c(cluster3_names, rep(NA, length(cluster1_names) - length(cluster3_names))),
cluster4 = c(cluster4_names, rep(NA, length(cluster1_names) - length(cluster4_names)))
)
kable(presentation_df)
| cluster1 | cluster2 | cluster3 | cluster4 |
|---|---|---|---|
| Taiwan | Singapore | Japan | Singapore |
| Romania | China | China | India |
| Bangladesh | Taiwan | China | China |
| India | India | China | Japan |
| Myanmar | Singapore | Taiwan | Thailand |
| Taiwan | Singapore | Singapore | Thailand |
| Japan | Singapore | Singapore | NA |
| Vietnam | Bulgaria | India | NA |
| Malaysia | Bangladesh | China | NA |
| Philippines | Malaysia | China | NA |
| Japan | Japan | China | NA |
| Japan | Japan | Philippines | NA |
| Taiwan | China | Thailand | NA |
| Romania | Vietnam | Vietnam | NA |
| Singapore | Japan | China | NA |
| Japan | Taiwan | China | NA |
| Mongolia | Vietnam | NA | NA |
| Taiwan | NA | NA | NA |
| Korea | NA | NA | NA |
| Philippines | NA | NA | NA |
| South Korea | NA | NA | NA |
| Japan | NA | NA | NA |
We first prepare the object for trade-off:
### allocate separate object for all trade-off calculation
average_utility <- colMeans(brkfst_part)
average_utility_df_all <- data.frame(level = names(average_utility),
avg_utility = average_utility)
average_utility_df_all <-
average_utility_df_all %>%
filter(level != "intercept")
average_utility_df_all <-
average_utility_df_all %>%
mutate(group =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
mutate(level_fct = factor(level)) %>%
mutate(rank = seq.int(1:length(average_utility_df_all$level))) %>%
mutate(order_rnk = level, rank) %>%
mutate(space_char = rep(c("L"), length(average_utility_df_all$level))) %>%
unite("lng_level", c("space_char","rank","level"))
average_utility_df_all <- average_utility_df_all %>%
mutate(rank = seq.int(1:length(average_utility_df_all$level))) %>%
mutate(lng_level = as.factor(lng_level)) %>%
mutate(lng_level = fct_reorder(lng_level, rank )) %>%
mutate(group_fct = factor(group, levels = c("Price", "Form", "PurchaseLocation",
"FunPackaging", "CognitiveSupport", "DigitalIntegration"
)))
Subsequently, we can calculate the average value of one monetary utility:
\(\frac{¥600 - ¥200}{0.513-(-0.572)}\) = ¥368.85
# average monetary value of 1 utiliy
# linear utility function
util_linear_value <- (600-200)/
(average_utility_df_all[average_utility_df_all$lng_level ==
"L_1_200",]$avg_utility-
average_utility_df_all[average_utility_df_all$lng_level ==
"L_3_600",]$avg_utility)
util_linear_value
## [1] 368.8475
# piece-wise utility function
util_piecewise_1 <- (600-400)/(average_utility["400"]-average_utility["600"])
util_piecewise_1
## 400
## 317.0478
util_piecewise_2 <- (400-200)/(average_utility["200"]-average_utility["400"])
util_piecewise_2
## 200
## 440.8789
To visualize the trade-off, we can plot:
tri_df_points <-
data.frame(
price = c(200, 600),
utility =
c(average_utility_df_all[average_utility_df_all$lng_level ==
"L_1_200",]$avg_utility,
average_utility_df_all[average_utility_df_all$lng_level ==
"L_3_600",]$avg_utility)
)
ggplot(tri_df_points,
aes(x = price, y = utility)) +
geom_point() + geom_line()
Going from no cognitive support to Caffeine and Alertness boost, the client would be willing to pay more:
# moving from none to caffeine or alertness boost
delta_cognitive_support_none_caffeine <- (average_utility_df_all[average_utility_df_all$lng_level=="L_14_Caffeine or Alertness boost",]$avg_utility -
average_utility_df_all[average_utility_df_all$lng_level=="L_13_None",]$avg_utility) * util_linear_value
delta_cognitive_support_none_caffeine
## [1] 75.81933
Going from no cognitive support to Natural Mood stabilizer, the client would be willing to pay more:
# moving from none to natural mood stabilizers
delta_cognitive_support_none_naturalmood <-
(average_utility_df_all[average_utility_df_all$lng_level=="L_15_Natural Mood Stabilizer",]$avg_utility -
average_utility_df_all[average_utility_df_all$lng_level=="L_13_None",]$avg_utility) * util_linear_value
delta_cognitive_support_none_naturalmood
## [1] 94.01379
Code for various tables.
To compute the parthworth by a specific variable, we can run:
## code for tables -----
### for variables
var_by <- "exercise_per_week_cut"
kable(
brkfst_cmb %>%
group_by(group_var = eval(as.name(paste(var_by)))) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-group_var) %>%
pivot_wider(id_cols = name, names_from = "group_var",
values_from = "value")
)
| name | 1-5 times | Never |
|---|---|---|
| L_1_200 | 0.5648571 | 0.3974211 |
| L_2_400 | 0.0333333 | 0.1159474 |
| L_3_600 | -0.5981667 | -0.5133684 |
| L_4_Bread and Pastries | 0.0090714 | 0.4248947 |
| L_5_Onigiri | 0.5631905 | 0.2647368 |
| L_6_Protein sticks | -0.5722143 | -0.6894737 |
| L_7_On Route to work | 0.4747857 | 0.5590526 |
| L_8_Within 150m | -0.1070000 | -0.2323158 |
| L_9_More than 150m | -0.3677143 | -0.3270526 |
| L_10_None | 0.3326190 | 0.4450000 |
| L_11_Attack on Titan | -0.1328571 | -0.0918421 |
| L_12_Doan Ritsu | -0.1998571 | -0.3532632 |
| L_13_None | -0.1348810 | -0.1946316 |
| L_14_Caffeine or Alertness boost | 0.0235476 | 0.1151053 |
| L_15_Natural Mood Stabilizer | 0.1113333 | 0.0794211 |
| L_16_None | -0.2365000 | -0.3736316 |
| L_17_Loyalty points | 0.3478571 | 0.2058421 |
| L_18_Nutrition Advice | -0.1113095 | 0.1677895 |
To investigate specific observations or subgroups we use the
filter() function, passing the variable and specific
observations, as below:
### for specific observations
kable(
brkfst_cmb %>%
filter(nickname %in% c("Marius", "Abigail", "Yun", "Matt", "Pup")) %>%
group_by(nickname) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-nickname) %>%
pivot_wider(id_cols = name, names_from = "nickname",
values_from = "value")
)
| name | Abigail | Marius | Matt | Pup | Yun |
|---|---|---|---|---|---|
| L_1_200 | 1.899 | 1.043 | 0.710 | 1.319 | 0.609 |
| L_2_400 | 0.094 | -0.326 | 0.341 | -0.225 | -0.065 |
| L_3_600 | -1.993 | -0.717 | -1.051 | -1.094 | -0.543 |
| L_4_Bread and Pastries | -0.728 | -0.402 | -0.902 | 0.634 | -0.547 |
| L_5_Onigiri | 0.609 | 0.739 | 0.739 | -1.246 | 1.681 |
| L_6_Protein sticks | 0.120 | -0.337 | 0.163 | 0.612 | -1.134 |
| L_7_On Route to work | 0.337 | 1.141 | 0.308 | 0.786 | -0.105 |
| L_8_Within 150m | 0.057 | -0.396 | -0.729 | -0.268 | -0.172 |
| L_9_More than 150m | -0.393 | -0.746 | 0.421 | -0.518 | 0.278 |
| L_10_None | 0.523 | 0.338 | 0.004 | 0.399 | 0.028 |
| L_11_Attack on Titan | 0.473 | 1.188 | -0.646 | -0.851 | 0.078 |
| L_12_Doan Ritsu | -0.996 | -1.525 | 0.641 | 0.453 | -0.105 |
| L_13_None | -0.486 | -0.430 | 0.404 | -0.446 | 0.167 |
| L_14_Caffeine or Alertness boost | 0.040 | -0.112 | -0.279 | 0.315 | -0.489 |
| L_15_Natural Mood Stabilizer | 0.446 | 0.542 | -0.125 | 0.130 | 0.322 |
| L_16_None | -0.420 | -1.563 | -0.396 | -0.446 | -0.233 |
| L_17_Loyalty points | 0.713 | 1.009 | -0.325 | 0.130 | -0.278 |
| L_18_Nutrition Advice | -0.293 | 0.554 | 0.721 | 0.315 | 0.511 |
To compare two specific countries, for example China and Japan, we can run:
## country comparison
brkfst_cmb %>%
filter(country2 %in% c("Japan", "China")) %>%
group_by(country2) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-country2) %>%
pivot_wider(id_cols = name, names_from = "country2",
values_from = "value")
## # A tibble: 18 × 3
## name China Japan
## <chr> <dbl> <dbl>
## 1 L_1_200 0.590 0.590
## 2 L_2_400 0.134 -0.0405
## 3 L_3_600 -0.724 -0.549
## 4 L_4_Bread and Pastries -0.164 0.252
## 5 L_5_Onigiri -0.147 0.761
## 6 L_6_Protein sticks 0.312 -1.01
## 7 L_7_On Route to work 0.593 0.375
## 8 L_8_Within 150m 0.0195 -0.278
## 9 L_9_More than 150m -0.612 -0.0977
## 10 L_10_None 0.0924 0.636
## 11 L_11_Attack on Titan -0.0485 -0.544
## 12 L_12_Doan Ritsu -0.0437 -0.0915
## 13 L_13_None -0.0725 -0.0403
## 14 L_14_Caffeine or Alertness boost -0.088 -0.138
## 15 L_15_Natural Mood Stabilizer 0.160 0.178
## 16 L_16_None -0.0361 -0.434
## 17 L_17_Loyalty points 0.124 0.505
## 18 L_18_Nutrition Advice -0.0879 -0.071
brkfst_cmb_plot <- brkfst_cmb %>%
filter(country2 %in% c("Japan", "China")) %>%
group_by(country2) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-country2) %>%
# mutate(country2 = factor(country2,
# levels = c("Japan", "China"))) %>%
mutate(name = factor(name,
levels = c("L_1_200",
"L_2_400",
"L_3_600",
"L_4_Bread and Pastries",
"L_5_Onigiri",
"L_6_Protein sticks",
"L_7_On Route to work",
"L_8_Within 150m",
"L_9_More than 150m",
"L_10_None",
"L_11_Attack on Titan",
"L_12_Doan Ritsu",
"L_13_None",
"L_14_Caffeine or Alertness boost",
"L_15_Natural Mood Stabilizer",
"L_16_None",
"L_17_Loyalty points",
"L_18_Nutrition Advice")))
ggplot(brkfst_cmb_plot, aes(x=name , y = value,
group = country2, fill=country2)) +
geom_col(position = "dodge") +
coord_flip() +
scale_x_discrete(limits = rev(levels(brkfst_cmb_plot$name))) +
geom_text(aes(label = format(round(value, 2), nsmall = 2)), vjust = -0.5)
#ggtitle(paste(iter, n_obs, sep = ", n =")) +
#guides(fill="none")
To see the parthworth only for the Japanese subgroup, we run:
brkfst_cmb %>%
filter(country2 %in% c("Japan")) %>%
group_by(country2) %>%
summarise_at(vars(L_1_200:`L_18_Nutrition Advice`),
mean , na.rm = TRUE) %>%
pivot_longer(-country2) %>%
# mutate(country2 = factor(country2,
# levels = c("Japan", "China"))) %>%
mutate(name = factor(name,
levels = c("L_1_200",
"L_2_400",
"L_3_600",
"L_4_Bread and Pastries",
"L_5_Onigiri",
"L_6_Protein sticks",
"L_7_On Route to work",
"L_8_Within 150m",
"L_9_More than 150m",
"L_10_None",
"L_11_Attack on Titan",
"L_12_Doan Ritsu",
"L_13_None",
"L_14_Caffeine or Alertness boost",
"L_15_Natural Mood Stabilizer",
"L_16_None",
"L_17_Loyalty points",
"L_18_Nutrition Advice"))) %>%
mutate(group_aggr =
c("Price", "Price", "Price",
"Form", "Form", "Form",
"PurchaseLocation", "PurchaseLocation", "PurchaseLocation",
"FunPackaging", "FunPackaging", "FunPackaging",
"CognitiveSupport", "CognitiveSupport","CognitiveSupport",
"DigitalIntegration", "DigitalIntegration", "DigitalIntegration"
)) %>%
arrange(desc(value))
## # A tibble: 18 × 4
## country2 name value group_aggr
## <chr> <fct> <dbl> <chr>
## 1 Japan L_5_Onigiri 0.761 Form
## 2 Japan L_10_None 0.636 FunPackaging
## 3 Japan L_1_200 0.590 Price
## 4 Japan L_17_Loyalty points 0.505 DigitalIntegration
## 5 Japan L_7_On Route to work 0.375 PurchaseLocation
## 6 Japan L_4_Bread and Pastries 0.252 Form
## 7 Japan L_15_Natural Mood Stabilizer 0.178 CognitiveSupport
## 8 Japan L_13_None -0.0403 CognitiveSupport
## 9 Japan L_2_400 -0.0405 Price
## 10 Japan L_18_Nutrition Advice -0.071 DigitalIntegration
## 11 Japan L_12_Doan Ritsu -0.0915 FunPackaging
## 12 Japan L_9_More than 150m -0.0977 PurchaseLocation
## 13 Japan L_14_Caffeine or Alertness boost -0.138 CognitiveSupport
## 14 Japan L_8_Within 150m -0.278 PurchaseLocation
## 15 Japan L_16_None -0.434 DigitalIntegration
## 16 Japan L_11_Attack on Titan -0.544 FunPackaging
## 17 Japan L_3_600 -0.549 Price
## 18 Japan L_6_Protein sticks -1.01 Form